package com.cpfmat.controller;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.cpfmat.common.CommonStringUtils;
import com.cpfmat.common.Contains;
import com.cpfmat.common.LogUtils;
import com.cpfmat.entity.SystemParam;
import com.cpfmat.service.ISystemParamService;
import com.cpfmat.vo.Company;
import com.cpfmat.vo.CustomParam;
import com.cpfmat.vo.HomeBigPicture;
import com.cpfmat.vo.Partner;
import com.cpfmat.vo.WebSite;
import com.cpfmat.vo.WorkTime;
import com.google.gson.Gson;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author zhangbin
 * @since 2018-07-30
 */
@Controller
public class SystemParamController {
	@Autowired
	private ISystemParamService systemParamService;

	@RequestMapping("/manage/systemParam/init")
	public ModelAndView initParam() {
		ModelAndView view = new ModelAndView("/manage/param/systemParam");
		
		Map<String, Object> paramMap = selectParam();
		view.addObject("companyT",paramMap.get("company"));
		view.addObject("partnersT",paramMap.get("partners"));
		view.addObject("webSiteT",paramMap.get("webSite"));
		view.addObject("workTimeT",paramMap.get("workTime"));
		view.addObject("picturesT",paramMap.get("pictures"));
		return view;
	}

	@SuppressWarnings("unchecked")
	@RequestMapping("/manage/systemParam/save")
	@ResponseBody
	public String saveParam(@RequestParam("paramJsonStr") String paramJsonStr) throws Exception {
		List<Map<String,String>> addList = new ArrayList<Map<String,String>>();
		
		Gson gson = new Gson();
		CustomParam jsonObject = gson.fromJson(paramJsonStr, CustomParam.class);
		
		Company company = jsonObject.getCompany();
		
		if(company != null){
			String type = "company";
			Field[] declaredFields = company.getClass().getDeclaredFields();
			for(Field field : declaredFields){
				field.setAccessible(true);
				String value = (String) field.get(company);
				if(StringUtils.isNotBlank(value)){
					Map<String,String> addMap = new HashMap<String,String>();
					addMap.put("type", type);
					addMap.put("key", field.getName());
					addMap.put("value", value);
					addList.add(addMap);
				}
			}
		}
		
		WebSite webSite = jsonObject.getWebSite();
		
		if(webSite != null){
			String type = "webSite";
			Field[] declaredFields = webSite.getClass().getDeclaredFields();
			for(Field field : declaredFields){
				field.setAccessible(true);
				String value = (String) field.get(webSite);
				if(StringUtils.isNotBlank(value)){
					Map<String,String> addMap = new HashMap<String,String>();
					addMap.put("type", type);
					addMap.put("key", field.getName());
					addMap.put("value", value);
					addList.add(addMap);
				}
			}
		}
		
		WorkTime workTime = jsonObject.getWorkTime();
		
		if(workTime != null){
			String type = "workTime";
			Field[] declaredFields = workTime.getClass().getDeclaredFields();
			for(Field field : declaredFields){
				field.setAccessible(true);
				String value = (String) field.get(workTime);
				if(StringUtils.isNotBlank(value)){
					Map<String,String> addMap = new HashMap<String,String>();
					addMap.put("type", type);
					addMap.put("key", field.getName());
					addMap.put("value", value);
					addList.add(addMap);
				}
			}
		}
		

		String type = "picture";
		List<HomeBigPicture> pictures = jsonObject.getPictures();
		Set<Integer> orderNumberSet = new HashSet<Integer>();
		// 为了避免麻烦，全部删了重新加
		boolean delPictureFlag = false;
		if(pictures != null && pictures.size() > 0){
			
			Iterator<HomeBigPicture> iterator = pictures.iterator();
			while(iterator.hasNext()){
				HomeBigPicture picture = iterator.next();
				if(picture != null){
					String orderNumber = picture.getOrderNumber();
					Integer orderNum = Integer.parseInt(orderNumber);
					orderNumber = formatOrderNum(orderNum);
					
					orderNumberSet.add(orderNum);
					Field[] declaredFields = picture.getClass().getDeclaredFields();
					for(Field field : declaredFields){
						field.setAccessible(true);
						if(!"orderNumber".equals(field.getName())){
							String value = (String) field.get(picture);
							if(StringUtils.isNotBlank(value)){
								Map<String,String> addMap = new HashMap<String,String>();
								addMap.put("type", type);
								addMap.put("key", orderNumber + "-" + field.getName());
								addMap.put("value", value);
								addList.add(addMap);
								delPictureFlag = true;
							}
						}
					}
				}
			}
		}
		else if(pictures != null){
			delPictureFlag = true;
		}
		
		if(pictures != null && orderNumberSet.size() != pictures.size()){
			return "ON_ER";
		}
		
		if(delPictureFlag){
			EntityWrapper<SystemParam> del = new EntityWrapper<SystemParam>();
			del.eq("PARAM_TYPE", type);
			systemParamService.delete(del);
		}

		String partnerType = "partner";
		List<Partner> parters = jsonObject.getPartners();
		Set<Integer> partnerOrderNumSet = new HashSet<Integer>();
		// 为了避免麻烦，全部删了重新加
		boolean delPartnerFlag = false;
		if(parters != null && parters.size() > 0){
			Iterator<Partner> iterator = parters.iterator();
			while(iterator.hasNext()){
				Partner partner = iterator.next();
				if(partner != null){
					String orderNumber = partner.getOrderNumber();
					Integer orderNum = Integer.parseInt(orderNumber);
					orderNumber = formatOrderNum(orderNum);
					
					partnerOrderNumSet.add(orderNum);
					Field[] declaredFields = partner.getClass().getDeclaredFields();
					for(Field field : declaredFields){
						field.setAccessible(true);
						if(!"orderNumber".equals(field.getName())){
							String value = (String) field.get(partner);
							if(StringUtils.isNotBlank(value)){
								Map<String,String> addMap = new HashMap<String,String>();
								addMap.put("type", partnerType);
								addMap.put("key", orderNumber + "-" + field.getName());
								addMap.put("value", value);
								addList.add(addMap);
								
								delPartnerFlag = true;
							}
						}
					}
				}
			}
		}
		else if(parters != null){
			delPartnerFlag = true;
		}
		
		if(parters != null && partnerOrderNumSet.size() != parters.size()){
			return "PO_ER";
		}
		
		if(delPartnerFlag){
			EntityWrapper<SystemParam> del = new EntityWrapper<SystemParam>();
			del.eq("PARAM_TYPE", partnerType);
			systemParamService.delete(del);
		}

		// 新加一遍
		Iterator<Map<String, String>> iterator = addList.iterator();
		while(iterator.hasNext()){
			Map<String, String> next = iterator.next();
			saveParam(next.get("type"), next.get("key"), next.get("value"));
		}

		// 保存完所有参数之后重新加载一次
		Map<String, Object> paramMap;
		try {
			paramMap = selectParam();
			
			Contains.company = (Company) paramMap.get("company");
			LogUtils.debug("重新加载公司参数");
			LogUtils.debug(Contains.company);
			
			Contains.pictures = (List<HomeBigPicture>) paramMap.get("pictures");
			LogUtils.debug("重新加载首页轮播图参数");
			LogUtils.debug(Contains.pictures);
			
			Contains.webSite = (WebSite) paramMap.get("webSite");
			LogUtils.debug("重新加载网站参数");
			LogUtils.debug(Contains.webSite);
			
			Contains.workTime = (WorkTime) paramMap.get("workTime");
			LogUtils.debug("重新加载工作时间参数");
			LogUtils.debug(Contains.workTime);
			
			Contains.partners = (List<Partner>) paramMap.get("partners");
			LogUtils.debug("重新加载合作伙伴");
			LogUtils.debug(Contains.partners);
		} catch (Exception e) {
			e.printStackTrace();
			LogUtils.error("保存成功，但是重新加载数据到通用对象时出现异常");
		}
		
		return "true";
	}
	
	private boolean saveParam(String type,String key,String value){
		LogUtils.debug("插入系统参数表数据");
		LogUtils.debug("param_type:" + type + "param_key:" + key + "param_value:" + value);
		try{
			SystemParam systemParam = new SystemParam();
			
			systemParam.setParamType(type);
			systemParam.setParamKey(key);
			
			EntityWrapper<SystemParam> ew = new EntityWrapper<SystemParam>(systemParam);
			
			SystemParam selectOne = systemParamService.selectOne(ew);
			

			Date now = new Date();
			if(selectOne != null){
				if(value == selectOne.getParamValue() || (value != null && value.equals(selectOne.getParamValue()))){
					return true;
				}
				selectOne.setParamValue(value);
				selectOne.setUpdateTime(now);
				selectOne.setUpdateCounts(selectOne.getUpdateCounts() + 1);
				systemParamService.updateById(selectOne);
			}
			else{
				SystemParam systemParam2 = new SystemParam();
				systemParam2.setSeqId(CommonStringUtils.getUUID());
				systemParam2.setDelFlag(0);
				systemParam2.setInsertTime(now);
				systemParam2.setParamKey(key);
				systemParam2.setParamType(type);
				systemParam2.setParamValue(value);
				systemParam2.setUpdateCounts(0);
				systemParam2.setUpdateTime(now);
				
				systemParamService.insert(systemParam2);
			}
			
			return true;
		} catch(Exception e){
			e.printStackTrace();
		}
		return false;
	}

	private Map<String,Object> selectParam(){
		EntityWrapper<SystemParam> select = new EntityWrapper<SystemParam>();
		select.eq("DEL_FLAG", 0);
		select.orderBy("PARAM_TYPE,PARAM_KEY");

		List<SystemParam> selectList = systemParamService.selectList(select);

		Company company = new Company();
		List<HomeBigPicture> pictures = new ArrayList<HomeBigPicture>();
		WebSite webSite = new WebSite();
		WorkTime workTime = new WorkTime();
		List<Partner> partners = new ArrayList<Partner>();

		Iterator<SystemParam> iterator = selectList.iterator();

		String lastPicturesOrderNumber = "";
		String lastPartnerOrderNumber = "";
		HomeBigPicture lastPicture = null;
		Partner lastPartner = null;

		while (iterator.hasNext()) {
			SystemParam systemParam = iterator.next();
			String type = systemParam.getParamType();
			String key = systemParam.getParamKey();
			String value = systemParam.getParamValue();

			try {
				if ("company".equals(type)) {
					Field field = company.getClass().getDeclaredField(key);
					field.setAccessible(true);
					field.set(company, value);
				} else if ("webSite".equals(type)) {
					Field field = webSite.getClass().getDeclaredField(key);
					field.setAccessible(true);
					field.set(webSite, value);
				} else if ("workTime".equals(type)) {
					Field field = workTime.getClass().getDeclaredField(key);
					field.setAccessible(true);
					field.set(workTime, value);

				} else if ("picture".equals(type)) {
					String[] keys = key.split("-");
					String orderNumber = keys[0];
					key = keys[1];

					if (!lastPicturesOrderNumber.equals(orderNumber)) {
						if (lastPicture != null)
							pictures.add(lastPicture);
						lastPicture = new HomeBigPicture();
						lastPicture.setOrderNumber(orderNumber);
					}
					Field field = lastPicture.getClass().getDeclaredField(key);
					field.setAccessible(true);
					field.set(lastPicture, value);

					lastPicturesOrderNumber = orderNumber;
				} else if ("partner".equals(type)) {
					String[] keys = key.split("-");
					String orderNumber = keys[0];
					key = keys[1];

					if (!lastPartnerOrderNumber.equals(orderNumber)) {
						if (lastPartner != null)
							partners.add(lastPartner);
						lastPartner = new Partner();
						lastPartner.setOrderNumber(orderNumber);
					}
					Field field = lastPartner.getClass().getDeclaredField(key);
					field.setAccessible(true);
					field.set(lastPartner, value);

					lastPartnerOrderNumber = orderNumber;
				}

			} catch (NoSuchFieldException | SecurityException e) {
				e.printStackTrace();
			} catch (IllegalArgumentException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			}
		}
		if(lastPicture != null) pictures.add(lastPicture);
		if(lastPartner != null) partners.add(lastPartner);
		
		Map<String, Object> paramMap = new HashMap<String, Object>();
		paramMap.put("pictures", pictures);
		paramMap.put("company", company);
		paramMap.put("webSite", webSite);
		paramMap.put("workTime", workTime);
		paramMap.put("partners", partners);
		return paramMap;
	}
	
	private String formatOrderNum(Integer orderNum) throws Exception{
		String orderNumber = null;
		if(orderNum == 0){
			orderNumber = "000";
		}
		else if(orderNum > 0 && orderNum < 10){
			orderNumber = "00" + orderNum;
		}
		else if(orderNum >= 10 && orderNum < 100){
			orderNumber = "0" + orderNum;
		}
		else if(orderNum >= 100 && orderNum < 1000){
			
		}
		else {
			throw new Exception("orderNumber错误");
		}
		return orderNumber;
	}
	
}
